---
title: Scalars
description: Guide for defining Scalar types in Pothos
---

## Adding Custom GraphQL Scalars

To add a custom scalar that has been implemented as GraphQLScalar from
[graphql-js](https://github.com/graphql/graphql-js) you need to provide some type information in
SchemaTypes generic parameter of the builder:

```typescript
const builder = new SchemaBuilder<{
  Scalars: {
    Date: {
      Input: Date;
      Output: Date;
    };
  };
}>({});

builder.addScalarType('Date', CustomDateScalar);
```

The Input type is the type that will be used when the type is used in an argument or `InputObject`.
The Output type is used to validate the resolvers return the correct value when using the scalar in
their return type.

For many scalars `Input` and `Output` will be the same, but they do not always need to match. The
Scalars generic can be used to change types for the built-in scalars.

For example, the defaults for the ID scalar might not be exactly what you want, you can customize
the values like so:

```typescript
const builder = new SchemaBuilder<{
  Scalars: {
    ID: {
      // type all ID arguments and input values as string
      Input: string;
      // Allow resolvers for ID fields to return strings, numbers, or bigints
      Output: string | number | bigint;
    };
  };
}>({});
```

## Adding Scalars from `graphql-scalars`

Similarly to adding your own custom scalars, you can utilize scalars from the
[graphql-scalars](https://the-guild.dev/graphql/scalars/docs) library by also providing the types
through the SchemaTypes generic parameter.

Note that when implementing the graphql-scalars library, the best types to use for `Input` and
`Output` types are _not_ always intuitive. For example, you might assume that the `JSON` type from
graphql-scalars would utilize the global `JSON` type, or another JSON type imported from a library
that tries to enumerate potential JSON values, but it is usually better to just use `unknown`. A
good place to start if you are unsure what type to use it the check the `codegenScalarType` inside
file where the scalar is defined by `graphql-scalars`
([BigInt scalar definition, for reference](https://github.com/Urigo/graphql-scalars/blob/6bdccebb27a7f9be7b5d01dfb052a3e9c17432fc/src/scalars/BigInt.ts#L92)).
This isn't defined for all scalars, and some scalars use `any` in which case `unknown` might be a
better option.

```typescript
import { DateResolver, JSONResolver } from 'graphql-scalars';

const builder = new SchemaBuilder<{
  Scalars: {
    JSON: {
      Input: unknown;
      Output: unknown;
    };
    Date: {
      Input: Date;
      Output: Date;
    };
  };
}>({});

builder.addScalarType('JSON', JSONResolver);
builder.addScalarType('Date', DateResolver);
```

## Defining your own scalars

```typescript
const builder = new SchemaBuilder<{
  Scalars: {
    PositiveInt: {
      Input: number;
      Output: number;
    };
  };
}>({});

builder.scalarType('PositiveInt', {
  serialize: (n) => n,
  parseValue: (n) => {
    if (n >= 0) {
      return n;
    }

    throw new Error('Value must be positive');
  },
});
```

## Using scalars

```typescript
builder.queryFields((t) => ({
  date: t.field({
    type: 'Date',
    resolve: () => new Date(),
  }),

  positive: t.field({
    type: 'PositiveInt',
    resolve: () => 5,
  }),
}));
```
